﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MineSweeper : MonoBehaviour
{

    public int col = 9;
    public int row = 9;
    public int MineCount = 20;
    // 安全区域个数，当countSafe == col * row - MineCount即为获胜
    private int countSafe;
    private float time;
    // 游戏结果：0-未开始；1-已开始；2-赢；3-输
    private int result;
    // 记录各个位置的状态，其中雷为-1，其余数字为九宫格内雷的个数
    private int[,] mine = new int[10,10];
    // 该区域是否已探查
    private int[,] open = new int[10,10];
    private System.Random rand = new System.Random();

    // Start is called before the first frame update
    void Start() {
        ReStart();
    }

    // Update is called once per frame
    void Update() {
        //开始计时
        if (result == 1)
            time += Time.deltaTime;
    }

    void OnGUI() {
        GUIStyle style = new GUIStyle();
        style.fontSize = 30;
        // 显示游戏时间
        int timeSec = (int) time;
        GUI.Label(new Rect(50, 75, 50, 50), "Time: ", style);
        if(timeSec != 0)
            GUI.Label(new Rect(150, 75, 50, 50), timeSec.ToString() + "s", style);
        
        // 显示游戏结果
        if (result == 3)
            GUI.Label(new Rect(50, 125, 100, 50), "You Lose.", style);
        else if (result == 2)
            GUI.Label(new Rect(50, 125, 100, 50), "You Win.", style);
        
        // 更换按钮样式
        if (GUI.Button(new Rect(100, 300, 100, 50), "Replay"))
            ReStart();

        // 打印游戏区域
        for(int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (GUI.Button(new Rect(400 + i * 50, 40 + j * 50, 50, 50), Block(i, j))) {
                    if (result == 0) {
                        Sweep(i, j);
                        result = 1;
                    }
                    if (result == 1)
                        Sweep(i, j);
                }

                // 游戏结束后显示所有地雷位置(将地雷10位置1，表示已探查)
                if ((result == 3 || result == 2) && mine[i,j] == -1)
                    open[i,j] = 1;
            }
        }
    }

    void ReStart()
    {
        //初始化
        time = 0;
        result = 0;
        countSafe = 0;
        // 全部初始化为0
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; ++j) {
                mine[i,j] = 0;
                open[i,j] = 0;
            }
        }
            

        // 随机摆放地雷
        for (int i = 0; i < MineCount; i++) {
            int tx = rand.Next(0, row);
            int ty = rand.Next(0, col);
            // 已经是地雷则跳过重来
            if(mine[tx,ty] == -1) {
                i--;
                continue;
            }
            else
                mine[tx,ty] = -1;
        }
        
        // 如果不是雷则计算该区域对应数字
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (mine[i,j] != -1)
                    mine[i,j] = CountMine(i, j);
            }    
        }
            
    }

    // 统计该地块附近地雷数
    int CountMine(int x, int y) {
        int count = 0;
        for (int i = x - 1; i <= x + 1; i++) {
            if (i >= 0 && i < row) {
                for (int j = y - 1; j <= y + 1; j++) {
                    if (j >= 0 && j < col && mine[i,j] == -1)
                        count++;
                }
            }
        }
        return count;
    }

    void Sweep(int x, int y) {

        // 碰到地雷直接返回
        if (mine[x,y] == -1) {
            result = 3;
            return;
        } else {
            // 安全区域增加
            countSafe++;
            // 十位数置1以表示该地块已探查
            open[x,y] = 1;
        }

        if (countSafe == col * row - MineCount) {
            result = 2;
            return;
        }
            

        // 周围有地雷，直接返回
        if (mine[x,y] != 0)
            return;

        // 周围没有地雷的话则对四周进行深度优先遍历，直到碰到数字为止
        for (int i = x - 1; i <= x + 1; i++) {
            if (i >= 0 && i < row) {
                for (int j = y - 1; j <= y + 1; j++) {
                    if (j >= 0 && j < row) {
                        // 若该地周围无地雷且未探查，探查该地块
                        if (open[i,j] == 0)
                            Sweep(i, j);
                    }
                }
            }
        }
    }

    

    //地块状态显示
    string Block(int x, int y) {
        if (open[x,y] == 0)
            return "";
        else
            return mine[x,y].ToString();
    }
}